/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is Forte for Java, Community Edition. The Initial
* Developer of the Original Code is Sun Microsystems, Inc. Portions
* Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.core;
import java.util.*;
import javax.swing.event.*;
import javax.swing.Action;
import javax.swing.KeyStroke;
import javax.swing.text.Keymap;
/** Implementation of standard key - action mappings.
*
* @author Dafe Simonek
*/
final class NbKeymap implements Keymap {
/** Name of this keymap */
String name;
/** Parent keymap */
Keymap parent;
/** Hashtable holding KeyStroke > Action mappings */
Map bindings;
/** Default action */
Action defaultAction;
/** hash table to map (Action -> ArrayList of KeyStrokes) */
Map actions;
/** Default constructor
*/
NbKeymap() {
this("Default", null); // NOI18N
}
NbKeymap(final String name, final Keymap parent) {
this.name = name;
this.parent = parent;
bindings = new HashMap();
}
public Action getDefaultAction() {
if (defaultAction != null) {
return defaultAction;
}
return (parent != null) ? parent.getDefaultAction() : null;
}
public void setDefaultAction(Action a) {
defaultAction = a;
fireChangeEvent(new ChangeEvent(this));
}
public String getName() {
return name;
}
public Action getAction(KeyStroke key) {
Action a = null;
synchronized (this) {
a = (Action) bindings.get(key);
}
if ((a == null) && (parent != null)) {
a = parent.getAction(key);
}
return a;
}
public KeyStroke[] getBoundKeyStrokes() {
int i = 0;
KeyStroke[] keys = null;
synchronized (this) {
keys = new KeyStroke[bindings.size()];
for (Iterator iter = bindings.keySet().iterator(); iter.hasNext(); ) {
keys[i++] = (KeyStroke) iter.next();
}
}
return keys;
}
public Action[] getBoundActions() {
int i = 0;
Action[] actionsArray = null;
synchronized (this) {
actionsArray = new Action[bindings.size()];
for (Iterator iter = bindings.values().iterator(); iter.hasNext(); ) {
actionsArray[i++] = (Action) iter.next();
}
}
return actionsArray;
}
public KeyStroke[] getKeyStrokesForAction(Action a) {
Map localActions = actions;
if (localActions == null) {
localActions = buildReverseMapping ();
}
List strokes = (List)localActions.get (a);
if (strokes != null) {
return (KeyStroke[])strokes.toArray(new KeyStroke[strokes.size ()]);
} else {
return new KeyStroke[0];
}
}
private Map buildReverseMapping () {
Map localActions = actions = new HashMap ();
synchronized (this) {
Set entries = bindings.entrySet();
for (Iterator it = bindings.entrySet().iterator(); it.hasNext(); ) {
Map.Entry curEntry = (Map.Entry)it.next();
Action curAction = (Action) curEntry.getValue();
KeyStroke curKey = (KeyStroke) curEntry.getKey();
List keysForAction = (List)localActions.get (curAction);
if (keysForAction == null) {
keysForAction = Collections.synchronizedList (new ArrayList (1));
localActions.put (curAction, keysForAction);
}
keysForAction.add (curKey);
}
}
return localActions;
}
public synchronized boolean isLocallyDefined(KeyStroke key) {
return bindings.containsKey(key);
}
public void addActionForKeyStroke(KeyStroke key, Action a) {
synchronized (this) {
bindings.put(key, a);
actions = null;
}
fireChangeEvent(new ChangeEvent(this));
}
void addActionForKeyStrokeMap(HashMap map) {
synchronized (this) {
for (Iterator it = map.keySet ().iterator (); it.hasNext (); ) {
Object key = it.next ();
bindings.put(key, map.get (key));
}
actions = null;
}
fireChangeEvent(new ChangeEvent(this));
}
public void removeKeyStrokeBinding(KeyStroke key) {
synchronized (this) {
bindings.remove(key);
actions = null;
}
fireChangeEvent(new ChangeEvent(this));
}
public void removeBindings() {
synchronized (this) {
bindings.clear();
actions = null;
}
fireChangeEvent(new ChangeEvent(this));
}
public Keymap getResolveParent() {
return parent;
}
public void setResolveParent(Keymap parent) {
this.parent = parent;
fireChangeEvent(new ChangeEvent(this));
}
/** Returns string representation - can be looong.
*/
public String toString() {
return "Keymap[" + name + "]" + bindings; // NOI18N
}
void fireChangeEvent (final ChangeEvent che) {
NbTopManager.change.firePropertyChange (NbTopManager.PROP_GLOBAL_KEYMAP, null, null);
}
}
/*
* Log
* 11 src-jtulach1.10 3/8/00 Jaroslav Tulach Proper synchronization.
* 10 src-jtulach1.9 1/13/00 Jaroslav Tulach I18N
* 9 src-jtulach1.8 1/5/00 Ian Formanek Removed obsoleted field
* 8 src-jtulach1.7 12/21/99 Ian Formanek Optimized adding multiple
* <action, shortcut> pairs into Keymap
* 7 src-jtulach1.6 12/1/99 Ian Formanek Fixed multiple KeyStrokes
* per Action bug
* 6 src-jtulach1.5 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun
* Microsystems Copyright in File Comment
* 5 src-jtulach1.4 5/5/99 Jaroslav Tulach Speeded up a bit.
* 4 src-jtulach1.3 4/1/99 David Simonek concurrent writing bug
* fixed (hopefully)
* 3 src-jtulach1.2 3/4/99 Jaroslav Tulach ChangeListener in
* TopManager
* 2 src-jtulach1.1 3/1/99 David Simonek icons etc..
* 1 src-jtulach1.0 3/1/99 David Simonek
* $
*/